package com.motion.controller;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.motion.dao.CourseActionDao;
import com.motion.dto.*;
import com.motion.generator.entity.*;
import com.motion.provider.OSSProvider;
import com.motion.result.Result;
import com.motion.result.ResultFactory;
import com.motion.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import ws.schild.jave.EncoderException;
import ws.schild.jave.MultimediaObject;
import ws.schild.jave.info.MultimediaInfo;

import java.io.File;
import java.io.IOException;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/api/course")
@Api("课程模块")
public class CourseController {
    @Autowired
    private CourseService courseService;
    @Autowired
    private UserDynamicService userDynamicService;
    @Autowired
    private OSSProvider ossProvider;
    @Autowired
    private UserCourseService userCourseService;
    @Autowired
    private CourseClassService courseClassService;
    @Autowired
    private CourseLinkService courseLinkService;
    @Autowired
    private UserSignInDayService userSignInDayService;
    @Autowired
    private CourseEvaluationService courseEvaluationService;
    @Autowired
    private ActionService actionService;
    @RequestMapping(value = "/try", method = RequestMethod.POST)
    public void test() {
//        LocalDateTime lastTime = LocalDateTime.of(2021, 6, 25,12, 30, 55);
//        Duration duration = Duration.between(lastTime, LocalDateTime.now());
//        System.out.println(duration.toNanos());
//        System.out.println(Duration.between(LocalDateTime.now(), lastTime).toNanos());
    }

    //课程详细获取
    @RequestMapping(value = "/courseId2Course", method = RequestMethod.POST)
    @ApiOperation(value = "课程获取",notes = "courseId获取")
    public Result courseId2Course(@RequestBody Course course){
        return ResultFactory.buildSuccessResult(null);
    }
    //课程筛选
//    @RequestMapping(value = "/getCourseById", method = RequestMethod.GET)
//    public Result getCourseById(@RequestParam Long page,@RequestParam Long size,@RequestParam String courseClassIdstr,@RequestParam int isOnline,@RequestParam int isHot){
//        CourseAbbDto courseAbbDto=new CourseAbbDto();
//        String sqlInStr=courseService.sqlStr(courseService.CourseSelection2List(courseClassIdstr));
//        courseAbbDto=courseService.sqlStr2ourseAbbDto(sqlInStr,isOnline,isHot,page,size);
//        return ResultFactory.buildSuccessResult(courseAbbDto);
//    }

    @RequestMapping(value = "/getCourseById", method = RequestMethod.GET)
    @ApiOperation(value = "课程筛选")
    public Result getCourseById(@RequestParam Long page,@RequestParam Long size,@RequestParam String courseClassIdstr,@RequestParam int isOnline,@RequestParam int isHot) {
        CourseAbbDto courseAbbDto = new CourseAbbDto();

//        此处筛选条件可能为空，此时直接返回结果为空，而不是处理空字符串
        //8.7 此处筛选条件可能为空，改完全选
        if (courseClassIdstr.equals("")){
//            CourseAbbDto nullResult = new CourseAbbDto();
//            nullResult.setHasNext(false);
//            nullResult.setCourseList(new ArrayList<>());
//            return ResultFactory.buildSuccessResult(nullResult);
            return ResultFactory.buildSuccessResult(courseService.all2courseAbbDto(isOnline,isHot,page,size));
        }
        List<List<Long>> listList=courseService.CourseSelection2LongList(courseClassIdstr);

        //此处筛选条件筛选结果可能为空[],后续要做异常处理
        List<CourseLink> courseLinks = courseLinkService.selectCourseLink(listList);
        System.out.println(courseLinks);
        if (courseLinks.isEmpty()){
            CourseAbbDto nullResult = new CourseAbbDto();
            nullResult.setHasNext(false);
            nullResult.setCourseList(new ArrayList<>());
            return ResultFactory.buildSuccessResult(nullResult);
        }
        Set<Long> longs=new HashSet<>();
        for (CourseLink item:courseLinks){
            longs.add(item.getCourseId());
        }
        return ResultFactory.buildSuccessResult(courseService.List2courseAbbDto(longs,isOnline,isHot,page,size));
    }

    //热门课程接口
    @RequestMapping(value = "/getHotCourse", method = RequestMethod.GET)
    @ApiOperation(value = "热门课程")
    public Result getHotCourse() {
        return ResultFactory.buildSuccessResult(courseService.getHotCourse(1L, 10L));
    }
    @RequestMapping(value = "/getRelatedCourse", method = RequestMethod.GET)
    public Result getRelatedCourse(@RequestParam Long courseId) {
//        String bp = courseService.getCourseById(courseId).getLabels();
        List<Long> tem = courseLinkService.getCourseClassId(courseId);
        if (tem.size()==0){
            return ResultFactory.buildSuccessResult(courseService.getHotCourse(1L, 10L));
        }
        List<Course> result = courseService.getCourseByLabels(tem);
        return ResultFactory.buildSuccessResult(courseService.CourseToAbb(result));
    }

    //课程详细获取
    @RequestMapping(value = "/getCourse", method = RequestMethod.POST)
    @ApiOperation(value = "获取详细课程")
    public Result getCourse(@RequestBody CourseActionDao courseActionDao) {
        //获取数据
        Long courseId=courseActionDao.getCourseId();
        String token=courseActionDao.getToken();
        if(StpUtil.getLoginIdByToken(token)==null){
            return ResultFactory.buildResultTokenError("token无效");
        }
        Long userId=Long.valueOf(StpUtil.getLoginIdByToken(token).toString());
//        Long userId=Long.valueOf(token);
        //根据courseId获取课程，并填充
        Course course = courseService.getCourseById(courseId);
        System.out.println(course);
        CourseActionDto courseActionDto=new CourseActionDto();
        BeanUtils.copyProperties(course,courseActionDto);
        System.out.println(courseActionDto);
        //设置labels
        List<Long> longList=courseLinkService.getCourseClassId(courseId);
        //List<Long> longList=courseService.StringToListLong(course.getLabels());
        if(!longList.isEmpty()) {
            courseActionDto.setLabelsName(courseService.courseClassIdList2CourseClassList(longList).stream().map(CourseClass::getClassValue).collect(Collectors.toList()));
        }else {
            courseActionDto.setLabelsName(new ArrayList<>());
        }
        //设置action
        List<Long> actionIdList = courseService.StringToListLong(course.getActions());
        List<Integer> countIdList = courseService.StringToIntList(course.getCounts());
        courseActionDto.setActionList(courseService.actionIdListAndCountList2ActionDtoList(actionIdList, countIdList));
        //设置是否收藏/是否预定
        int label_temp = courseService.ifUserCollectCourse(userId,courseId);
        courseActionDto.setCollected((label_temp/10)!=0);

        courseActionDto.setBooked((label_temp%10)!=0);
        return ResultFactory.buildSuccessResult(courseActionDto);
    }
    //课程名模糊查询获取
    @RequestMapping(value = "/getCourseByName", method = RequestMethod.GET)
    @ApiOperation(value = "课程名模糊查询获取")
    public Result getCourseByName(@RequestParam Long page,@RequestParam Long size,@RequestParam String courseName){
        CourseAbbDto courseAbbDto=new CourseAbbDto();
        IPage<Course> courseIPage=courseService.keyword2CourseIPage(courseName,page,size);
        courseAbbDto.setCourseList(courseService.CourseToAbb(courseIPage.getRecords()));
        courseAbbDto.setHasNext(courseIPage.getTotal()>page*size);
        return ResultFactory.buildSuccessResult(courseAbbDto);
    }

    @ApiOperation(value = "课程完成界面")
    @RequestMapping(value = "/courseCompleted", method = RequestMethod.GET)
    public Result courseCompleted(@RequestParam int time,@RequestParam String token,@RequestParam Long courseId){
        if(StpUtil.getLoginIdByToken(token)==null){
            return ResultFactory.buildResultTokenError("token无效");
        }
        Long userId=Long.valueOf(String.valueOf(StpUtil.getLoginIdByToken(token)));
//        Long userId = 5L;

        //获得上次完成课程时间，判断是否在一天之内
        LocalDateTime baseTime = LocalDateTime.now().withHour(0).withMinute(0).withSecond(0);
        LocalDateTime lastTime = userDynamicService.courseCompletedRevisionTime(userId,time);
        Duration duration = Duration.between(lastTime, baseTime);
        CourseCompleteDto result = new CourseCompleteDto();
        try{
            String courseName=courseService.getCourseById(courseId).getCourseName();
            //判断是否大于24h，而不是在当天。。要改
            if (duration.toNanos() > 0){
                userSignInDayService.insertUserSignInDay(time, courseName, userId);
            }else{
                userSignInDayService.updataUserSignInDay(time, courseName, userId);
            }
            result.setCourseName(courseName);
            result.setDuration(time);
        }catch (Exception e){
            //传入的courseId是错误的，不存在对应的课程
            return ResultFactory.buildFailResult("course doesn't exist");
        }

        //courseService.coursePlayCountAddOne()中
        int total = courseService.coursePlayCountAddOne(courseId, userId);
        result.setTotalTime(total);
        return ResultFactory.buildSuccessResult(result);
    }
    //最近练习
    @ApiOperation(value = "最近练习")
    @RequestMapping(value = "/getPracticedCourse", method = RequestMethod.GET)
    public Result getPracticedCourse(@RequestParam String token, @RequestParam Long page, @RequestParam Long size){
        // 最近练习不需要分页，只显示最近5条
        if(StpUtil.getLoginIdByToken(token)==null){
            return ResultFactory.buildResultTokenError("token无效");
        }
        Long userId=Long.valueOf(String.valueOf(StpUtil.getLoginIdByToken(token)));
//        Long userId = 2L;
        IPage<UserCourse> ipage = userCourseService.getResentWatched(userId, page, size);
        List<UserCourse> userCourses = ipage.getRecords();
        try{
            // 提取最近练习的course的List，为了减少查询次数
            if(userCourses.size()!=0) {
                List<Long> courseIdList = new ArrayList<>();
                for (UserCourse userCourse : userCourses) {
                    courseIdList.add(userCourse.getCourseId());
                }
                // 表示成courseId-Course的形式
                HashMap<Long, Course> hashMap = new HashMap<>();
                for (Course course : courseService.courseIdList2CourseList(courseIdList)) {
                    hashMap.put(course.getCourseId(), course);
                }
                HashMap<Long, String> hashMap2 = new HashMap<>();
                for (CourseClass courseClass : courseClassService.getCourseClass()) {
                    hashMap2.put(courseClass.getCourseClassId(), courseClass.getClassValue());
                }

                List<CourseAbb> result = new ArrayList<>();
                CourseAbb courseAbb = new CourseAbb();
                Course course;
                for (UserCourse userCourse : userCourses) {
                    course = hashMap.get(userCourse.getCourseId());
                    if(course==null)
                        continue;
                    courseAbb = new CourseAbb();
                    courseAbb.setCourseId(userCourse.getCourseId());
                    courseAbb.setCourseName(course.getCourseName());
                    courseAbb.setBackgroundUrl(course.getBackgroundUrl());
                    courseAbb.setTargetAge(course.getTargetAge());
//                courseAbb.setLabels(courseClassService.idsHashNames(course.getLabels().split(";"), hashMap2));
                    courseAbb.setLabels(courseLinkService.getCourseLabel(course.getCourseId()));
                    courseAbb.setOnline(course.getOnLine());
                    courseAbb.setPracticed(userCourse.getPlayCount());
                    result.add(courseAbb);
                }
                CourseAbbDto courseAbbDto = new CourseAbbDto();
                courseAbbDto.setCourseList(result);
                courseAbbDto.setHasNext(page * size < ipage.getTotal());
                return ResultFactory.buildSuccessResult(courseAbbDto);
            }
            CourseAbbDto courseAbbDto = new CourseAbbDto();
            courseAbbDto.setCourseList(new ArrayList<>());
            courseAbbDto.setHasNext(false);
            return ResultFactory.buildSuccessResult(courseAbbDto);
        }catch (Exception e){
            // 此处异常通常是因为 usercourses 为空，所以选择不报错
            return ResultFactory.buildSuccessResult(new ArrayList<>());
        }

    }

    @ApiOperation(value = "获取用户收藏课程")
    @RequestMapping(value = "/getCollectionCourse", method = RequestMethod.GET)
    public Result getCollectionCourse(@RequestParam String token, @RequestParam Long page, @RequestParam Long size){
        if(StpUtil.getLoginIdByToken(token)==null){
            return ResultFactory.buildResultTokenError("token无效");
        }
        Long userId=Long.valueOf(String.valueOf(StpUtil.getLoginIdByToken(token)));
//        Long userId = 5L;
        IPage<UserCourse> ipage = userCourseService.getCollected(userId, page, size);
        List<UserCourse> userCourses = ipage.getRecords();
        CourseAbbDto courseAbbDto = new CourseAbbDto();
        try{
            // 提取course的List，为了减少查询次数
            if(userCourses.size()!=0){
                List<Long> courseIdList = new ArrayList<>();
                for(UserCourse userCourse : userCourses){
                    courseIdList.add(userCourse.getCourseId());
                }
                // 表示成courseId-Course的形式
                HashMap<Long, Course> hashMap = new HashMap<>();
                for(Course course : courseService.courseIdList2CourseList(courseIdList)){
                    hashMap.put(course.getCourseId(), course);
                }
                HashMap<Long, String> hashMap2 = new HashMap<>();
                for(CourseClass courseClass:courseClassService.getCourseClass()){
                    hashMap2.put(courseClass.getCourseClassId(), courseClass.getClassValue());
                }

                List<CourseAbb> result = new ArrayList<>();
                CourseAbb courseAbb = null;
                for(UserCourse userCourse:userCourses){
                    Course course = hashMap.get(userCourse.getCourseId());
                    if(course==null)
                        continue;
                    courseAbb = new CourseAbb();
                    courseAbb.setCourseId(userCourse.getCourseId());
                    courseAbb.setCourseName(course.getCourseName());
                    courseAbb.setBackgroundUrl(course.getBackgroundUrl());
                    courseAbb.setTargetAge(course.getTargetAge());
//                    courseAbb.setLabels(courseClassService.idsHashNames(course.getLabels().split(";"), hashMap2));
                    courseAbb.setLabels(courseLinkService.getCourseLabel(course.getCourseId()));
                    courseAbb.setOnline(course.getOnLine());
                    courseAbb.setPracticed(userCourse.getPlayCount());
                    result.add(courseAbb);
                }

                courseAbbDto.setCourseList(result);
                courseAbbDto.setHasNext(page*size<ipage.getTotal());
                return ResultFactory.buildSuccessResult(courseAbbDto);
            }
            courseAbbDto.setCourseList(new ArrayList<>());
            courseAbbDto.setHasNext(false);
            return ResultFactory.buildSuccessResult(courseAbbDto);
        }catch (Exception e){
            System.out.println(e);
            return ResultFactory.buildFailResult(null);
        }
    }
    /*
    //oss课程上传,课程命名格式课程id+courseHeadportrait.jpg
    @RequestMapping(value = "/uploadCourse", method = RequestMethod.POST)
    public Result uploadCourse(@RequestParam("file") MultipartFile image, @RequestParam Long courseId){

    }*/
    @ApiOperation(value = "收藏课程")
    @RequestMapping(value = "/collectCourse", method = RequestMethod.GET)
    public Result collectCourse(@RequestParam String token, @RequestParam Long courseId, @RequestParam int flag){
        if(StpUtil.getLoginIdByToken(token)==null){
            return ResultFactory.buildResultTokenError("token无效");
        }
        Long userId=Long.valueOf(String.valueOf(StpUtil.getLoginIdByToken(token)));
//        Long userId = 2L;
        if (userCourseService.collectCourse(userId, courseId, flag)){
            return ResultFactory.buildSuccessResult(null);
        }
        return ResultFactory.buildFailResult(null);
    }
    @ApiOperation(value = "预约课程课程")
    @RequestMapping(value = "/bookCourse", method = RequestMethod.GET)
    public Result bookCourse(@RequestParam String token, @RequestParam Long courseId, @RequestParam int flag){
        if(StpUtil.getLoginIdByToken(token)==null){
            return ResultFactory.buildResultTokenError("token无效");
        }
        Long userId=Long.valueOf(String.valueOf(StpUtil.getLoginIdByToken(token)));
//        Long userId = 2L;
        if (userCourseService.bookCourse(userId, courseId, flag)){
            return ResultFactory.buildSuccessResult(null);
        }
        return ResultFactory.buildFailResult("课程已上线");
    }
    @ApiOperation(value = "课程评价")
    @RequestMapping(value = "/courseEvaluation", method = RequestMethod.GET)
    public Result courseEvaluation(@RequestParam String token, @RequestParam Long courseId,
                                   @RequestParam @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") LocalDateTime createtime, @RequestParam int evaluation){
        if(StpUtil.getLoginIdByToken(token)==null){
            return ResultFactory.buildResultTokenError("token无效");
        }
        Long userId=Long.valueOf(String.valueOf(StpUtil.getLoginIdByToken(token)));
        CourseEvaluation courseEvaluation=new CourseEvaluation();
        courseEvaluation.setCourseId(courseId);
        courseEvaluation.setCreateTime(createtime);
        courseEvaluation.setEvaluation(evaluation);
        courseEvaluation.setUserId(userId);
        return ResultFactory.buildSuccessResult(courseEvaluationService.insertCourseEvaluation(courseEvaluation));
    }
    //课程视频大小
    @ApiOperation(value = "上传视频")
    @RequestMapping(value = "/updatavideo", method = RequestMethod.POST)
    public Result updatavideo(@RequestParam("headPortrait") MultipartFile video, @RequestParam String token){
        if(StpUtil.getLoginIdByToken(token)==null){
            return ResultFactory.buildResultTokenError("token无效");
        }
        Long userId = Long.valueOf(String.valueOf(StpUtil.getLoginIdByToken(token)));
//        Long userId = 2L;
        File file=new File(video.getOriginalFilename());
        try {
            FileUtils.copyInputStreamToFile(video.getInputStream(),file);
        } catch (IOException e) {
            e.printStackTrace();
        }
        Long time=0L;
        MultimediaObject instance=new MultimediaObject(file);
        MultimediaInfo resfult = null;
        try {
            resfult = instance.getInfo();
        } catch (EncoderException e) {
            e.printStackTrace();
        }
        time=resfult.getDuration()/1000L;
        file.delete();
        if (!video.isEmpty()) {
            try {
                String url = ossProvider.fileUpload(video.getInputStream(), String.valueOf(userId)+String.valueOf(LocalDateTime.now())+video.getName()+".mp4",1);
                videoDto request=new videoDto();
                request.setDuration(time);
                request.setSize(video.getSize());
                request.setUrl(url);
                return ResultFactory.buildSuccessResult(request);
            } catch (IOException e) {
                e.printStackTrace();
                return ResultFactory.buildFailResult("头像视频失败" + e.getMessage());
            }
        } else {
            return ResultFactory.buildFailResult("上传视频失败");
        }
    }

    //账号密码登录
    @ApiOperation(value = "账号密码登录")
    @RequestMapping(value = "/loginByAccount", method = RequestMethod.POST)
    public Result loginByAccount(@RequestBody User user){
        return ResultFactory.buildSuccessResult(user);
    }
}
